#pragma once

#include "kwdb/config.h"
#include "kwdb/point.h"
#include "kwdb/status.h"
#include <vector>
#include <string>
#include <memory>

namespace kwdb {

/**
 * ILP (InfluxDB Line Protocol) Client for KWDB
 *
 * Provides HTTP-based time-series data ingestion using the InfluxDB Line Protocol format.
 * Supports:
 * - TLS/SSL encryption
 * - Bearer Token & Basic Auth
 * - GZIP compression
 * - Batch writes
 *
 * Example usage:
 *   IngestConfig config;
 *   config.ingest_endpoint = "127.0.0.1:9091";
 *   config.security.gzip = true;  // Enable compression
 *
 *   IlpClient client(config);
 *   Point point("metrics");
 *   point.add_tag("host", "server1");
 *   point.add_field("cpu", 45.6);
 *
 *   Status status = client.write(point);
 */
class IlpClient {
public:
    /**
     * Create an ILP client with configuration
     * @param config Client configuration including endpoint, security, timeout
     */
    explicit IlpClient(const IngestConfig& config);
    ~IlpClient();

    /**
     * Write a single point
     * @param point Data point to write
     * @return Status of the operation
     */
    Status write(const Point& point);

    /**
     * Write multiple points in a batch
     * @param points Vector of data points
     * @return Status of the operation
     */
    Status batch_write(const std::vector<Point>& points);

    /**
     * Write raw ILP format string
     * @param line_protocol ILP formatted string
     * @return Status of the operation
     */
    Status write_raw(const std::string& line_protocol);

    /**
     * Flush any buffered data (for future batching support)
     * @return Status of the operation
     */
    Status flush();

private:
    class IlpClientImpl;
    std::unique_ptr<IlpClientImpl> impl_;
};

/**
 * Convert a Point to InfluxDB Line Protocol format
 *
 * Format: measurement,tag1=val1,tag2=val2 field1=val1,field2=val2 timestamp
 *
 * @param point The point to convert
 * @return ILP formatted string
 */
std::string point_to_ilp(const Point& point);

/**
 * Convert multiple points to ILP format (one per line)
 * @param points Vector of points
 * @return ILP formatted string with newlines
 */
std::string points_to_ilp(const std::vector<Point>& points);

/**
 * Escape special characters in ILP format
 * @param value String to escape
 * @param context Context for escaping (measurement, tag_key, tag_value, field_key)
 * @return Escaped string
 */
std::string ilp_escape(const std::string& value, const std::string& context);

} // namespace kwdb